import 'dart:async';

import 'package:built_collection/built_collection.dart';
import 'package:equatable/equatable.dart';
import 'package:mobile_app.core/core/domain/entities/email_app.dart';
import 'package:mobile_app.core/core/domain/entities/learning_content/collection_list_item/collection_list_item.dart';
import 'package:mobile_app.core/core/domain/entities/learning_content/lexical_item/lexical_item.dart';
import 'package:mobile_app.core/core/domain/entities/learning_info/learning_info.dart';
import 'package:mobile_app.core/core/domain/entities/premium_access_status.dart';
import 'package:mobile_app.core/core/domain/helpers/handle_learning_activity/helper.dart';
import 'package:mobile_app.core/core/domain/repositories/learning_content_repository/repository.dart';
import 'package:mobile_app.home.core/core/domain/helpers/apply_collection_list_item_update/helper.dart';
import 'package:mobile_app.home.core/core/domain/helpers/apply_lexical_item_addition_to_custom_collection/helper.dart';
import 'package:mobile_app.home.learning.spaced_repetitions/spaced_repetition_page/domain/entities/card_infos/card_info.dart';
import 'package:mobile_app.home.learning.spaced_repetitions/spaced_repetition_page/domain/helpers/get_memorization_card_actions/helper.dart';

part 'result.dart';

abstract class AddMemorizationCardLexicalItemToCustomCollection {
  MemorizationCardLexicalItemAdditionToCustomCollectionResult call({
    required MemorizationCardInfo currentCardInfo,
    required String customCollectionId,
    required BuiltMap<String, LexicalItem> lexicalItemMap,
    required BuiltList<CollectionListItem> collectionListItems,
    required PremiumAccessStatus premiumAccessStatus,
    required BuiltList<EmailApp> availableEmailApps,
    required LearningInfo learningInfo,
  });
}

class AddMemorizationCardLexicalItemToCustomCollectionImpl
    implements AddMemorizationCardLexicalItemToCustomCollection {
  const AddMemorizationCardLexicalItemToCustomCollectionImpl({
    required ApplyCollectionListItemUpdate applyCollectionListItemUpdate,
    required ApplyLexicalItemAdditionToCustomCollection applyLexicalItemAdditionToCustomCollection,
    required GetMemorizationCardActions getMemorizationCardActions,
    required HandleLearningActivity handleLearningActivity,
    required LearningContentRepository learningContentRepository,
  })  : _applyCollectionListItemUpdate = applyCollectionListItemUpdate,
        _applyLexicalItemAdditionToCustomCollection = applyLexicalItemAdditionToCustomCollection,
        _getMemorizationCardActions = getMemorizationCardActions,
        _handleLearningActivity = handleLearningActivity,
        _learningContentRepository = learningContentRepository;

  final ApplyCollectionListItemUpdate _applyCollectionListItemUpdate;
  final ApplyLexicalItemAdditionToCustomCollection _applyLexicalItemAdditionToCustomCollection;
  final GetMemorizationCardActions _getMemorizationCardActions;
  final HandleLearningActivity _handleLearningActivity;

  final LearningContentRepository _learningContentRepository;

  @override
  MemorizationCardLexicalItemAdditionToCustomCollectionResult call({
    required MemorizationCardInfo currentCardInfo,
    required String customCollectionId,
    required BuiltMap<String, LexicalItem> lexicalItemMap,
    required BuiltList<CollectionListItem> collectionListItems,
    required PremiumAccessStatus premiumAccessStatus,
    required BuiltList<EmailApp> availableEmailApps,
    required LearningInfo learningInfo,
  }) {
    final updatedCustomCollection = _applyLexicalItemAdditionToCustomCollection(
      lexicalItemId: currentCardInfo.lexicalItem.id,
      customCollectionId: customCollectionId,
      collectionListItems: collectionListItems,
    );

    final updatedCollectionListItems = _applyCollectionListItemUpdate(
      updatedCollectionListItem: updatedCustomCollection,
      collectionListItems: collectionListItems,
    );

    final updatedCardActions = _getMemorizationCardActions(
      lexicalItem: currentCardInfo.lexicalItem,
      lexicalItemMap: lexicalItemMap,
      collectionListItems: updatedCollectionListItems,
      premiumAccessStatus: premiumAccessStatus,
      availableEmailApps: availableEmailApps,
    );

    final updatedCurrentCardInfo = currentCardInfo.copyWith(
      cardActions: () => updatedCardActions,
    );

    final updatedLearningInfo = _handleLearningActivity(
      learningInfo: learningInfo,
    );

    final result = MemorizationCardLexicalItemAdditionToCustomCollectionResult(
      currentCardInfo: updatedCurrentCardInfo,
      collectionListItems: updatedCollectionListItems,
      learningInfo: updatedLearningInfo,
    );

    unawaited(_learningContentRepository.saveCollectionListItems(
      collectionListItems: updatedCollectionListItems,
    ));

    return result;
  }
}
